package cn.lili.modules.order.order.callback;

import cn.hutool.core.collection.CollectionUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.event.TransactionCommitSendMQEvent;
import cn.lili.common.thread.ThreadConfig;
import cn.lili.common.utils.StringUtils;
import cn.lili.common.vo.ResponseBean;
import cn.lili.exchange.AmqpExchangeProperties;
import cn.lili.modules.goods.client.GoodsClient;
import cn.lili.modules.goods.client.GoodsSkuClient;
import cn.lili.modules.goods.entity.dos.Goods;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.goods.entity.dto.GoodsSearchParams;
import cn.lili.modules.goods.entity.enums.GoodsAuthEnum;
import cn.lili.modules.goods.entity.enums.GoodsMarketEnum;
import cn.lili.modules.goods.entity.vos.yunxin.CallBackVO;
import cn.lili.modules.order.order.entity.dos.OrderItem;
import cn.lili.modules.order.order.entity.vo.GoodsSkuMap;
import cn.lili.modules.order.order.service.MessageTypeFlowService;
import cn.lili.modules.order.order.service.OrderItemService;
import cn.lili.modules.order.order.service.OrderService;
import cn.lili.routing.GoodsRoutingKey;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 商品修改
 */
@Slf4j
@Service("goods.alter")
public class GoodsAlterService implements MessageType{

    @Autowired
    private GoodsClient goodsClient;
    @Autowired
    private GoodsSkuClient goodsSkuClient;
    @Autowired
    private MessageTypeFlowService messageTypeFlowService;
    @Autowired
    private ApplicationEventPublisher applicationEventPublisher;
    @Autowired
    private AmqpExchangeProperties amqpExchangeProperties;
    @Autowired
    private Cache cache;
    @Autowired
    private ThreadConfig threadConfig;
    @Autowired
    private OrderItemService orderItemService;

    @Override
    @Transactional
    @ShardingTransactionType(TransactionType.BASE)
    public ResponseBean execute(CallBackVO callBackVO) {
        log.info("goods.undercarriage == {}", JSONObject.toJSONString(callBackVO));
        //保存回调消息记录
        messageTypeFlowService.saveCall(callBackVO);

        List<String> list = new ArrayList<>();
        list.add(String.valueOf(callBackVO.getProduct_id()));
        List<JSONObject> platformGoodsDetail = goodsClient.getPlatformGoodsDetail(list);

        List<Goods> goodsList = goodsClient.getByThirdPartyPlatformId(callBackVO.getProduct_id());
        List<GoodsSku> goodsSkus = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(goodsList)) {
            for (Goods goods : goodsList) {
                goods.setGid(Integer.valueOf(goods.getThirdPartyPlatformId()));
            }
            goodsSkus = goodsSkuClient.getGoodsSkuByGoodsIdList(goodsList.stream().map(Goods::getId).map(String::valueOf).collect(Collectors.toList()));
        }
        log.info("execute  goodsSkus == {}", JSONObject.toJSONString(goodsList));
        GoodsSkuMap goodsSkuMap = new GoodsSkuMap();
        goodsSkuMap.setPlatformGoodsDetail(platformGoodsDetail);
        goodsSkuMap.setGoodsList(goodsList);
        Map<String, List> map = goodsClient.goodsSkusConversion(goodsSkuMap);

        Boolean change = false;
        List goodsSku1 = map.get("goods_sku");
        Map<String, String> existMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(goodsSku1)) {
            List<LinkedHashMap> goodsSku = (List<LinkedHashMap>) goodsSku1;
            //自己平台
            for (GoodsSku skus : goodsSkus) {
                //第三方
                for (LinkedHashMap linkedHashMap : goodsSku) {
                    GoodsSku sku = JSONObject.parseObject(JSONObject.toJSONString(linkedHashMap), GoodsSku.class);
//                }
//                for (GoodsSku sku : goodsSku) {
                    if (skus.getThirdPartyPlatformId() != null && skus.getThirdPartyPlatformId().equals(sku.getThirdPartyPlatformId())) {
                        String thirdPartyPlatformId = existMap.get(skus.getThirdPartyPlatformId());
                        //已处理过的就直接跳过
                        if (StringUtils.isNotEmpty(thirdPartyPlatformId)) {
                            log.info("已处理过的就直接跳过 == {}", thirdPartyPlatformId);
                            continue;
                        }
                        existMap.put(skus.getThirdPartyPlatformId(), skus.getThirdPartyPlatformId());
                        Integer display = 0;
                        if (skus.getMarketEnable().equals(GoodsMarketEnum.UPPER.name())) {
                            display = 1;
                        }
                        if (skus.getMarketEnable().equals(GoodsMarketEnum.DOWN.name())) {
                            display = 0;
                        }
                        //上下架变动
                        if (!display.equals(sku.getIs_display())) {
                            log.info("上下架变动  原来状态== {} ， 现在状态 == {} ， 0下，1上" , display , sku.getIs_display());
                            //下架
                            if (sku.getIs_display().equals(0)) {
                               Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()-> {
                                    this.undercarriage(callBackVO);
                               });
                                continue;
                            }
                            //上架
                            if (sku.getIs_display().equals(1)) {
                                Objects.requireNonNull(threadConfig.getAsyncExecutor()).execute(()-> {
                                    this.onSale(callBackVO);
                                });
                                continue;
                            }
                        }
                        //有其他数据变动
                        change = true;
                        break;
                    }
                }
            }
        }
        //将商品删除，重新拉取
        if (change && CollectionUtil.isNotEmpty(goodsList)) {
            boolean isRemove = false;
            log.info("execute   goodsList === {} ",  JSONObject.toJSONString(goodsList));
            List<String> goodsIds = goodsList.stream().map(Goods::getId).collect(Collectors.toList());
            //如果是下单的，库存变动(最近30分钟这个订单有人下单)，则不删除重新拉取
            LambdaQueryWrapper<OrderItem> orderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
            orderItemLambdaQueryWrapper.in(OrderItem::getGoodsId, goodsIds);
            LocalDateTime currentTime = LocalDateTime.now();
            orderItemLambdaQueryWrapper.between(OrderItem::getCreateTime, currentTime.minus(Duration.ofMinutes(30)), currentTime);
            List<OrderItem> orderItemList = orderItemService.list(orderItemLambdaQueryWrapper);
            List<String> orderItemGoodsIdList = orderItemList.stream().map(OrderItem::getGoodsId).toList();
            if (CollectionUtil.isNotEmpty(orderItemGoodsIdList)) {
                isRemove = true;
            }
            if (isRemove) {
                return new ResponseBean(0, "操作成功", new HashMap<>());
            }
            Optional<Goods> optionalGoods = goodsList.stream()
                    .filter(g -> StringUtils.isNotEmpty(g.getStoreId()))
                    .findFirst();
            if (CollectionUtil.isNotEmpty(goodsIds) && optionalGoods.isPresent()) {
                log.info("goodsIds == {},  optionalGoods == {}", JSONObject.toJSONString(goodsIds), JSONObject.toJSONString(optionalGoods.get()));
                goodsClient.removeGoods(goodsIds, optionalGoods.get().getStoreId());
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            goodsClient.addGoods(callBackVO.getProduct_id());
        }

        return new ResponseBean(0, "操作成功", new HashMap<>());
    }

    /**
     * 上架商品
     * @param callBackVO
     */
    public void onSale(CallBackVO callBackVO) {
        Goods goods = new Goods();
        goods.setThirdPartyPlatformId(callBackVO.getProduct_id());
        goods.setMarketEnable(GoodsMarketEnum.UPPER.name());
        boolean b = goodsClient.updateGoods(goods);

        // 发送生成商品索引信息
        applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("生成商品").exchange(amqpExchangeProperties.getGoods()).routingKey(GoodsRoutingKey.GENERATOR_GOODS_INDEX).message(goods.getId()).build());
    }

    public void updatePrice(String id, Double cost, String goodsId, CallBackVO callBackVO) {
        List<GoodsSku> skuList = new ArrayList<>();
        GoodsSku goodsSku = new GoodsSku();
        goodsSku.setId(id);
        goodsSku.setCost(cost);
        goodsSku.setPrice(cost * 1.05);
        skuList.add(goodsSku);
        goodsSkuClient.updateBatchById(skuList);

        Goods goods = new Goods();
        List<String> list = new ArrayList<>();
        list.add(goodsId);
        List<GoodsSku> skuListClient = goodsSkuClient.getGoodsSkuByGoodsIdList(list);

        //把最低价格更新到商品上去。
        Double minPrice = null;
        if (CollectionUtil.isNotEmpty(skuListClient)) {
            minPrice = skuListClient.stream().sorted(Comparator.comparing(GoodsSku::getPrice)).collect(Collectors.toList()).get(0).getPrice();
        }
        if (minPrice != null) {
            goods.setPrice(minPrice);
        }
        goods.setId(goodsId);
        goodsClient.updateById(goods);

        //下架掉
        undercarriage(callBackVO);
    }

    /**
     * 下架商品
     * @param callBackVO
     */
    public void undercarriage(CallBackVO callBackVO) {
        log.info("goods.undercarriage == {}", JSONObject.toJSONString(callBackVO));
        //根据第三方平台id，获取商品信息。
        List<Goods> goodsList = goodsClient.getByThirdPartyPlatformId(callBackVO.getProduct_id());
        log.info("根据第三方平台id，获取商品信息 == {} ", JSONObject.toJSONString(goodsList));
        List<String> skuIdList = new ArrayList<>();
        List<GoodsSku> skuList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(goodsList)) {
            skuList = goodsSkuClient.getGoodsSkuByGoodsIdList(goodsList.stream().map(Goods::getId).collect(Collectors.toList()));
            if (CollectionUtil.isNotEmpty(skuList)) {
                skuIdList = skuList.stream().map(GoodsSku::getId).map(String::valueOf).collect(Collectors.toList());
            }
        }

        //下架商品
        Goods goods = new Goods();
        goods.setThirdPartyPlatformId(callBackVO.getProduct_id());
        goods.setMarketEnable(GoodsMarketEnum.DOWN.name());
        goods.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
        goodsClient.updateGoods(goods);
        log.info("下架商品sku skuList == {}", JSONObject.toJSONString(skuList));
        if (CollectionUtil.isNotEmpty(skuList)) {
            for (GoodsSku goodsSku : skuList) {
                goodsSku.setMarketEnable(GoodsMarketEnum.DOWN.name());
                goodsSku.setAuthFlag(GoodsAuthEnum.TOBEAUDITED.name());
            }
            goodsSkuClient.updateBatchById(skuList);
        }

        //删除缓存 + 索引
        List<String> goodsCacheKeys = new ArrayList<>();
        List<String> goodsSkuCacheKeys = new ArrayList<>();
        List<String> goodsIds = goodsList.stream().map(Goods::getId).collect(Collectors.toList());

        // 遍历商品缓存key
        goodsIds.forEach(goodsId -> goodsCacheKeys.add(CachePrefix.GOODS.getPrefix() + goodsId));
        // 遍历商品sku缓存key
        skuIdList.forEach(skuId -> goodsSkuCacheKeys.add(CachePrefix.GOODS_SKU.getPrefix() + skuId));
        // 发送删除商品信息
        log.info("开始发送删除商品信息");
        applicationEventPublisher.publishEvent(TransactionCommitSendMQEvent.builder().source("删除商品").exchange(amqpExchangeProperties.getGoods()).routingKey(GoodsRoutingKey.GOODS_DELETE).message(goodsIds).build());
        log.info("结束发送删除商品信息");
        // 清除缓存
        cache.multiDel(goodsCacheKeys);
        cache.multiDel(goodsSkuCacheKeys);
    }

}
